﻿using Microsoft.Extensions.DependencyInjection;
using PmSoft;
using PmSoft.Exceptions;

namespace Modules.System.Role
{
    /// <summary>
    /// 角色业务逻辑类
    /// </summary>
    [UseDI(ServiceLifetime.Scoped)]
    public class RoleService
    {
        private readonly SysRoleRepository roleRepository;
        private readonly SysRoleMenuRepository roleMenuRepository;
        private readonly SysUserRoleRepository userRoleRepository;

        public RoleService(SysRoleRepository roleRepository,
            SysRoleMenuRepository roleMenuRepository,
            SysUserRoleRepository userRoleRepository)
        {
            this.roleRepository = roleRepository;
            this.roleMenuRepository = roleMenuRepository;
            this.userRoleRepository = userRoleRepository;
        }

        /// <summary>
        /// 获取全部角色
        /// </summary>
        /// <returns></returns>
        public IEnumerable<SysRole> GetAllRoles()
        {
            return roleRepository.GetAll();
        }

        /// <summary>
        /// 创建角色
        /// </summary>
        /// <param name="role"></param>
        public void CreateRole(SysRole role)
        {
            roleRepository.Insert(role);
        }

        /// <summary>
        /// 修改角色状态
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="status"></param>
        public bool UpdateRoleStatus(int roleId, RoleStatus status)
        {
            var role = GetSysRole(roleId);
            if (role == null)
                throw new BusinessException("角色不存在");
            return roleRepository.UpdateRoleStatus(role, status);
        }

        /// <summary>
        /// 全量更新角色
        /// </summary>
        /// <param name="role"></param>
        public void UpdateRole(SysRole role)
        {
            roleRepository.Update(role);
        }

        /// <summary>
        /// 删除角色
        /// </summary>
        /// <param name="roleId"></param>
        public void DeleteRole(SysRole role)
        {
            IEnumerable<SysUserRole> sysUserRoles = userRoleRepository.GetUserRolesByRoleId(role.RoleId);
            if (sysUserRoles.Any())
                throw new BusinessException($"删除失败，角色{role.Name}下面有用户，不允许删除");
            roleRepository.Delete(role);
        }

        /// <summary>
        /// 删除多个角色
        /// </summary>
        /// <param name="RoleIds"></param>
        public void DeleteRoles(IEnumerable<int> RoleIds)
        {
            IEnumerable<SysRole> roles = roleRepository.PopulateEntitiesByEntityIds(RoleIds);
            foreach (SysRole role in roles)
                DeleteRole(role);
        }

        /// <summary>
        /// 获取角色信息
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public SysRole? GetSysRole(int roleId)
        {
            return roleRepository.Get(roleId);
        }

        /// <summary>
        /// 更新用户与角色关系
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="roleIds"></param>
        public void UpdateUserRoles(int userId, IEnumerable<int> roleIds)
        {
            userRoleRepository.CreateOrUpdate(userId,
                roleIds.Select(m => new SysUserRole { UserId = userId, RoleId = m }));
        }

        /// <summary>
        /// 更新角色与菜单关系
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="menuIds"></param>
        public void UpdateRoleMenus(int roleId, string roleCode, IEnumerable<int> menuIds)
        {
            roleMenuRepository.CreateOrUpdate(roleId, roleCode,
                menuIds.Select(m => new SysRoleMenu { RoleId = roleId, MenuId = m }));
        }

        /// <summary>
        /// 获取用户的角色集合
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public IEnumerable<SysRole> GetRolesByUserId(int userId)
        {
            var userRoles = userRoleRepository.GetUserRolesByUserId(userId);
            return roleRepository.PopulateEntitiesByEntityIds(userRoles.Select(m => m.RoleId));
        }

        /// <summary>
        /// 获取角色的菜单ID集合
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public IEnumerable<int> GetRoleMenuIds(int roleId)
        {
            return roleMenuRepository.GetRoleMenuByRoleId(roleId).Select(m => m.MenuId);
        }

        /// <summary>
        /// 根据角色ID集合获取角色信息集合
        /// </summary>
        /// <param name="roleIds"></param>
        /// <returns></returns>
        public IEnumerable<SysRole> GetRoles(IEnumerable<int> roleIds)
        {
            return roleRepository.PopulateEntitiesByEntityIds(roleIds);
        }

        /// <summary>
        /// 获取菜单关联角色
        /// </summary>
        /// <param name="menuId"></param>
        /// <returns></returns>
        public IEnumerable<SysRole> GetRolesByMenuId(int menuId)
        {
            var roleMenus = roleMenuRepository.GetRoleMenuByMenuId(menuId);

            return roleRepository.PopulateEntitiesByEntityIds(roleMenus.Select(m => m.RoleId)).Where(m => m.Status == RoleStatus.Normal);
        }

        /// <summary>
        /// 角色分页
        /// </summary>
        /// <param name="query"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IPagedList<SysRole> GetRoles(RoleQuery query, int pageIndex, int pageSize)
        {
            return roleRepository.GetRoles(query, pageIndex, pageSize);
        }
    }
}